<?php

function UnauthorizedDeath($msg = null) {
    if(! $msg)
        $msg = _("Unauthorized access");
    die($msg);
}

$charsets = array(
    "UTF-8",
    "UTF-16",
    "ISO-8859-1",
    "ISO-8859-15",
    "Windows-1252",
    "Windows-1251",
);


    // mbstring currently implements the following encoding detection
    // filters. If there is an invalid byte sequence for the following
    // encodings, encoding detection will fail. For ISO-8859-*,
    // mbstring always detects as ISO-8859-*. For UTF-16, UTF-32, UCS2
    // and UCS4, encoding detection will fail always. 

    // UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, 
    // JIS, ISO-2022-JP

function file_append_contents($path, $str) {
    return file_put_contents($path, $str, FILE_APPEND);
}

function _dplog($str) {
    global $transient_path;
    $logpath = build_path($transient_path, "log");
    file_append_contents($logpath, std_datetime());
    file_append_contents($logpath, $str);
}

function dplog($str) {
    _dplog($str);
}

function RedirectToLogin() {
    // global $relPath, $site_url;
    // require_once $relPath."metarefresh.inc";
    redirect_to_home();
}

function DefaultLocale() {
    global $User;
    $User->Language()
        ? $User->Language()
        : "en";
}

function SimpleHeader($title = "") {
    return NotSoSimpleHeader(array("title" => $title));
}

function SimpleFooter() {
    return "\n</body></html>";
}

function NotSoSimpleHeader($arg) {
// function NotSoSimpleHeader($title = "", $css = "", $js = "", 
                    // $onload = "", $jsurl = "", $cssurl = "") {

    global $relPath;
    global $css_url;
    global $site_name;

    $title = isset($arg['title']) 
                ? $arg['title'] 
                : $site_name;
    $langcode   = DefaultLocale();
    $css        = isset($arg['css']) ? $arg['css'] : "";
    $js         = isset($arg['js']) ? $arg['js'] : "";
    $onload     = isset($arg['onload']) ? $arg['onload'] : "";
    $jsurl      = isset($arg['jsurl']) ? $arg['jsurl'] : "";
    $cssurl     = isset($arg['cssurl']) ? $arg['cssurl'] : "";

return 
"<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>$title</title>
".($jsurl != "" ? "<script src='$jsurl'></script>":"")."
".($cssurl != "" ? "<link type='text/css' rel='stylesheet' 
                                        href='$cssurl'>":"")."

<link type='text/css' rel='stylesheet' href='{$css_url}/dp.css'>
<script type='text/javascript'>
$js
</script>
<style type='text/css'>
$css
</style>
</head>
".($onload == "" ? "<body>" : "<body onload='$onload'>");
}

function is_utf8($string) {
    return $string === mb_convert_encoding(
            mb_convert_encoding($string, 'UTF-32', 'UTF-8'),
            'UTF-8', 'UTF-32');
}

function is_8859_1($str) {
    return mb_detect_encoding($str, 'ISO-8859-1') == 'ISO-8859-1';
}

function from_utf8($str) {
    return utf8_decode($str);
}

function utf8_to_utf8($str) {
    return iconv("UTF-8", "UTF-8//IGNORE", $str);
}

function to_utf8($str) {
    return utf8_encode($str);
}

function to_encoding($str, $encoding) {
    return iconv("UTF-8", $encoding."//IGNORE", $str);
}

function to_encoding_with_translit($str, $encoding) {
    return iconv("UTF-8", $encoding."//TRANSLIT", $str);
}

function apparent_encoding($text) {
    return is_utf8($text)
        ? "UTF-8"
        : mb_detect_encoding($text);
}

function from_encoding($encoding, $text) {
    return mb_convert_encoding($text, "UTF-8", $encoding);
    // return iconv($charset, "UTF-8", $text);
}

function utf8_to_ascii($text) {
    return from_encoding("ASCII", $text);
}

function from_iso_8859_15($text) {
    return from_charset("ISO-8859-15", $text);
}

function is_charset($charset, $text) {
    return mb_check_encoding($text, $charset);
}

function uppercase($str) {
    return mb_convert_case($str, MB_CASE_UPPER);
}

function lowercase($str) {
    return mb_convert_case($str, MB_CASE_LOWER);
}

function titlecase($str) {
    return mb_convert_case($str, MB_CASE_TITLE);
}

function left($str, $len) {
    return mb_substr($str, 0, $len);
}

function bleft($str, $len) {
    return substr($str, 0, $len);
}

function right($str, $len) {
    if($len >= mb_strlen($str))
        return $str;

    return mb_substr($str, strlen($str) - $len);
}

function mid($str, $start, $len = -1) {
    if($len < 0)
        return mb_substr($str, $start);
    try {
    return $len >= 0 
            ? mb_substr($str, $start, $len)
            : mb_substr($str, $start);
    }
    catch(Exception $e) {
        say("mid exception $start $len");
        throw $e;
    }
}

function bmid($str, $start, $len = -1) {
    if($len < 0)
        return substr($str, $start);

    try {
    return $len >= 0 
            ? substr($str, $start, $len)
            : substr($str, $start);
    }
    catch(Exception $e) {
        say("bmid exception start=$start len=$len");
        throw $e;
    }
}

function bmiddle($str, $pos1, $pos2 = 0) {
    if($pos2 == 0)
        return bmid($str, $pos1);

    $len = $pos2 - $pos1;
    if($len > 0)
        return bmid($str, $pos1, $len);
    say("bmiddle fail: len $len pos1 $pos1 pos2 $pos2");
    assert(false);
    return "";
}

function middle($str, $pos1, $pos2 = 0) {
    if($pos2 == 0)
        return mid($str, $pos1);

    $len = $pos2 - $pos1;
    if($len > 0)
        return mid($str, $pos1, $len);
    say("middle fail: len $len pos1 $pos1 pos2 $pos2");
    assert(false);
    return "";
}

//   SQL


function SqlQuote($str) {
    return ($str == "") ? "NULL" : "'{$str}'";
}

function SqlInteger($num) {
    return is_null($num) ? "NULL" : intval($num);
}

// tracing and debugging

function StackDump() {
    array_walk(debug_backtrace(),
        create_function('$a,$b','print "{$a[\'function\']}()(".basename($a[\'file\']).":{$a[\'line\']}); ";'));
}

function say($var) {
    echo "<br />$var<br />";
}

function html_nowrap($str) {
    return preg_replace("/\n/", "<br />", $str);
}

function pre($var) {
    echo "<pre>$var</pre>";
}

function FromUrl() {
    return $_SERVER['REQUEST_URI'];
}

/*
function ProjectsUrl() {
    global $projects_url;
    return $projects_url;
}

function ProjectUrl($projectid) {
    return ProjectsUrl()."/$projectid";
}

function ProjectUploadPath($projectid) {
    global $transient_path;
    $path = build_path($transient_path, $projectid);
    return build_path($path, "loadfiles");
}

function ProjectDownloadUrl($projectid) {
    return ProjectsUrl()."projects_url/$projectid/$projectid.zip";
}
*/

/*
function ProjectPageUrl($projectid, $pagecode) {
	return ProjectUrl($projectid) . "/$pagecode/$pagecode.png";	
}
*/

function coalesce($ary) {
    if(! is_array($ary))
        return $ary;
    foreach($ary as $val)
    {
        if(!empty($val))
            return $val;
    }
    return null;
}

function ReplaceText($text, $newtext, $index, $length) {
    return ($index > 0 
                ? left($text, $index) 
                : "")
            . $newtext
            . mb_substr($text, $index + $length);
}

function multimatch($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match_all($regex, $text, $matches, PREG_SET_ORDER);
    return $matches;
}

/*

function matchoffsets($regex, $flags, $text) {
    $m = match_multi_offsets($regex, $flags, $text);
    return $m[0];
}

function match_multi_offsets($regex, $flags, $text, $n = 0) {
    // array of two-value arrays = 0-matchstr and 1-offset
    // [0][$i][0] = whole-regex-match str (--[1] offset)
    // [1] "   "  = first-regex-arg str ditto
    $arglists = regex_offsets($regex, $flags, $text);
    $nargs = count($arglists);
    $nmatches = count($arglists[0]);

    // say("nargs $nargs");
    // say("nmatches $nmatches");

    if($nargs == 0)
        return array();

    for($i = 0; $i < $nargs; $i++)
    {
        $alist = $arglists[$i];
        $ary = array();
        for($j = 0; $j < $nmatches; $j++)
        {
            $ary[] = new matchoffset(
                $alist[$j][0], $alist[$j][1]);
        }
        $aries[] = $ary;
    }
    return $aries;
}
*/

function ReplaceSubstr($str, $repl, $pos, $len) {
    return bleft($str, $pos).$repl.bmid($str, $pos+$len-1);
}

function CountReplaceRegex($ptn, $repl, $flags, &$text) {
    $ptn = "~".$ptn."~".$flags;
    $text = preg_replace($ptn, $repl, $text, -1, $n);
    return $n;
}

function ReplaceRegex($ptn, $repl, $flags, $text) {
    if(is_array($ptn))
        foreach($ptn as &$p)
            $p = "~".$p."~".$flags;
    else
        $ptn = "~".$ptn."~".$flags;
    return preg_replace($ptn, $repl, $text);
}

function ReplaceOneRegex($ptn, $repl, $flags, $text) {
    $ptn = "~".$ptn."~".$flags;
    return preg_replace($ptn, $repl, $text, 1);
}

function ReplaceMultiRegex($ptn, $repl, $flags, $text) {
    $ptn = "~".$ptn."~".$flags;
    return preg_replace($ptn, $repl, $text, -1);
}

function ReplaceLastRegex($ptn, $repl, $flags, $text) {
    $matcharray = LastRegexMatch($ptn, $flags, $text);
    if(! is_array($matcharray))
        return $text;
    list($match, $ipos) = $matcharray;

    $str = bleft($text, $ipos-1) 
        . ReplaceRegex($ptn, $repl, $flags, $match)
        . bmiddle($text, $ipos + strlen($match));
    return $str;
}

// returns offset from $start, or -1 for not found.
function RegexOffset($regex, $flags, $text, $start = 0) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match(
            $regex, $text, $match, PREG_OFFSET_CAPTURE, $start);
    return $n > 0 ? $match[0][1]: -1;
}

function regex_offset($regex, $flags, $text, $start = 0) {
    $regex = "~".$regex."~".$flags;
    // say($regex);
    $n = preg_match(
            $regex, $text, $match, PREG_OFFSET_CAPTURE, $start);
    return $n > 0 ? $match : array();
}

function regex_offsets($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE);
    return $matches;
}

function regex_offset_both($regex, $flags, $text, $start = 0) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match(
            $regex, $text, $match, PREG_OFFSET_CAPTURE, $start);
    return $n > 0 ? $match[0] : null;
}

// returns the "match array" i.e. match string and offset4
function FirstRegexMatch($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE);
    $match = $matches[0][0];
    return $n > 0 ? $match : null;
}

// returns the "match array" i.e. match string and offset4
function LastRegexMatch($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE);
    return $n > 0 ? end($matches[0]) : null;
}

function RegexMatches($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match_all($regex, $text, $match);
    return $match[0];
}

function RegexMatch($regex, $flags, $text, $index = 0, $offset = 0) {
    $regex = "~".$regex."~".$flags;
    $n = preg_match(
            $regex, $text, $matches, PREG_OFFSET_CAPTURE, $index);
    // return first array item
    return $matches[$index];
}

function RegexCount($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    return preg_match_all($regex, $text, $matches);
}

function RegexSplit($regex, $flags, $text) {
    $regex = "~".$regex."~".$flags;
    return preg_split($regex, $text);
}

/*
function TextOffsetArray($text, $regex) {
    $n = preg_match_all($regex, 
                $text, $matches, PREG_OFFSET_CAPTURE);
    $ary = array();
    foreach($matches as $match)
    {
        // $m is an array, with sub-arrays each 2 elements
        foreach($match as $m)
        {
            $ary[$m[1]] = $m[0];
        }
    }
    return $ary;
}
*/

// convert tabs to single spaces
function dp_detab($text) {
    return preg_replace("/\t+/", " ", $text);
}

// remove control characters
// ref: http://stackoverflow.com/questions/1497885/remove-control-characters-from-php-string
function dp_decontrol($text) {
    return preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/',
            '', $text);

}

// boolean
function findstr($text, $str) {
    return preg_match("^".$str."^", $text);
}

function findistr($text, $str) {
    return preg_match("/".$str."/i", $text);
}

function dp_fix_newlines($text) {
    return preg_replace( '/\r(?!\n)/m', "\r\n", 
           preg_replace( '/(?<!\r)\n/m', "\r\n", $text));
}

function dp_trim($text) {
    // top:    blank lines at end of entire string
    // bottom: eol whitespace all lines
    return      preg_replace("/ +$/D", "", 
           preg_replace('/(\S) +([\r\n])/', '\1\2', $text));
}

/*
function normalize($text) {
    return 
        dp_trim(
            dp_fix_newlines(
                dp_decontrol(
                    dp_detab($text)
        )));
}
*/

// for making strings comparable (sorta)
function despace($text) {
    return preg_replace("/ +/gu", " ", $text);
}

function yy_m_d($val = null) {
    return y_m_d($val);
}

function y_m_d($val = null) {
    return empty($val)
        ? date('y-m-d')
        : date($val);
}

function yyyy_m_d($val = null) {
    return empty($val)
        ? date('Y-m-d')
        : date($val);
}

function start_of_month($val = null) {
    if(empty($val)) $val = time();
    $Ym1 = strftime("%Y-%m-1", $val);
    return strtotime($Ym1);
}

function end_of_month($val = null) {
    if(empty($val)) $val = time();
    $y = strftime("%Y", $val);
    $m = strftime("%m", $val);
    if($m == 12) {
        $Y++;
        $m = 1;
    }
    else {
        $m++;
    }

    $Ym1 = sprintf("%s-%s-1", $Y, $m);
    return start_of_month($Ym1) - 1; 
}

function pretty_date_time($ts) {
    if(empty($ts))
        return "--" ;
    else
    return strftime("%c", $ts) ;
}

function now() {
    return time();
}

function std_datetime($val = 0) {
    if($val == 0)
        return std_datetime(now());
    else
        return strftime("%A, %B %e, %Y at %H:%M", $val);
}

function std_date($val) {
    if($val == 0)
        return "";
    else
    return strftime("%A, %B %e, %Y", $val);
}

function std_time($val) {
    if($val == 0)
        return "";
    else
    return strftime("%X", $val);
}
function yy_mm_dd_hh_nn($val) {
    return strftime("%y-%m-%d %H:%M", $val);
}

function yy_mm_dd_hh_nn_ss($val) {
    return strftime("%y-%m-%d %H:%M:%S", $val);
}
function yymmdd() {
    return strftime('%y%m%d');
}

function Month_day($val) {
    return strftime("%b %e", $val);
}
function day_Month($val) {
    return strftime("%e %b", $val);
}

function yyyymmdd( $val = null ) {
    return empty( $val )
        ? strftime('%Y-%m-%d')
        : strftime('%Y-%m-%d', $val );
}

function weeks_ago($val) {
    return intval(days_ago($val) / 7);
}

function days_ago($val) {
    return intval(hours_ago($val) / 24);
}

function hours_ago($val) {
    return intval(minutes_ago($val) / 60);
}

function minutes_ago($val) {
    return intval(seconds_ago($val) / 60);
}

function seconds_ago($val) {
    return time() - $val;
}

function one_minute() {
    return 60;
}

function one_hour() {
    return 60 * one_minute();
}

function one_day() {
    return 24 * one_hour();
}

function one_week() {
    return 7 * one_day();
}

function one_minute_ago() {
    return time() - one_minute();
}

function one_hour_ago() {
    return time() - one_hour();
}

function one_day_ago() {
    return time - one_day();
}

function one_week_ago() {
    return time - one_week();
}

function dptoday() {
    return new dpdate();
}

function TimeStampString() {
    return date('m-d-y H:i:s');
}

function init_timer() {
    _timer(true);
}

function get_timer() {
    return number_format(_timer(), 3);
}

function say_timer() {
    say("time: ".get_timer());
}

function _timer($is_init = false) {
    static $_start;
    if($is_init) {
        $_start = microtime(true);
        return 0.0;
    }
    else if(! isset($_start)) {
        say("default timer init");
        _timer(true);
        return 0.0;
    }
    else {
        return microtime(true) - $_start;
    }
}

function LogMsg($msg) {
    global $dpdb;
    global $User;
    $user = ($User == null  ? "(logging in)" : $User->Username() );
    $sql = "
        INSERT INTO log (username, eventtime, logtext)
        VALUES ('$user', 
                UNIX_TIMESTAMP(), 
                '${msg}')";
    $dpdb->SqlExecute($sql);
}

function DivertToLogin($dest = null) {
    require_once "metarefresh.inc";
    do_redirect(DP_ROOT_URL."/login.php", "Please Log In");
}

function DivertBack() {
    require_once "metarefresh.inc";
    do_redirect(RefererUrl());
}

function RefererUrl() {
    return $_SERVER['HTTP_REFERER'];
}

function ThisPageUrl() {
    return "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
}
function ThisUrl() {
    return $_SERVER['PHP_SELF'];
}

function ThisFullUrl() {
    return "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
}

function is_current_page($link) {
    return findstr($link, ThisUrl());
}

/*
function ActiveUrl() {
    return $_SERVER['PHP_SELF'];
}
*/

function h( $str ) {
    return htmlspecialchars( $str, ENT_QUOTES, "UTF-8" ) ;
}

function UrlSelf() {
    return $_SERVER['PHP_SELF'];
}

function self_url() {
    return $_SERVER['PHP_SELF'];
}

function ReferringUrl() {
    return $_SERVER['REQUEST_URI'];
}

function reamp($str) {
    return preg_replace("/\&amp;/u", "&", $str);
}
function unamp($str) {
    return preg_replace("/\&/u", "&amp;", $str);
}

function UserPmUrl($username) {
    $id = UserID($username);
    return URL_INBOX."/privmsg.php?mode=post&amp;u=$id";
}

function mklink($url, $prompt = null) {
    if(empty($prompt))
        $prompt = $url;
    return "<a href='{$url}'>{$prompt}</a>";
}

function mkmailto($url, $prompt = null) {
    if(empty($prompt))
        $prompt = $url;
    return "<a href='mailto:{$url}'>{$prompt}</a>";
}

function send_string($filename, $str) {
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename={$filename}");
    echo $str;
    exit;
}

function send_file($path) {

    if(! file_exists($path)) {
        dump("request to send phantom file $path."); 
        return;
    }

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($path));
    ob_clean();
    flush();
    readfile($path);
    exit;
}

function temp_file_path($prefix) {
    return tempnam(sys_get_temp_dir(), $prefix);
}

function dump_memory_size() {
    dump("memory: ".memory_get_usage());
}

function text_lines($text) {
    return preg_split("/\n/u", $text);
}

function build_path($path, $filename) {
    // trim off leading and trailing slashes
    if(substr($filename, 0, 1) == '/') {
        $filename = substr($filename, 1, 1000);
    }

    if(substr($path, -1, 1) == '/') {
        $ret = $path . $filename;
    } else {
        $ret = $path . '/' . $filename;
    }
    return $ret;
}

function htmlsafe($value) {
  return htmlspecialchars($value, ENT_QUOTES);
}

function html_comment($str) {
    return 
"<!--
$str 
-->
";
}

function permit_path($path) {
    chmod($path, 0777);
}

function PrettySql( $sql ) {
    return str_replace( "\n", "<br />\n", $sql ) ;
}

function _die($msg) {
    die(_($msg));
}

function DieSql( $sql ) {
    die( PrettySql( $sql ) ) ;
}

/*
function ProjectUrl($projectid)
{
    return URL_PROJECT."?projectid=$projectid";
}
*/

/*
function ProjectPageUrl($projectid, $pagecode)
{
	return ProjectUrl($projectid) . "/$pagecode/$pagecode.png";	
}

function ThumbFilePath($projectid, $pagecode)
{
        return ProjectPagePath($projectid, $pagecode)
        ."/".$this->ThumbFileName();
}

function ThumbUrl($projectid, $pagecode)
{
    return ProjectsUrl()
        ."/".$projectid
        ."/".$pagecode
        ."/".ThumbFileName($pagecode) ;
}

function ThumbFileName($pagecode)
{
    return "thumb.".$pagecode.".png";
}
*/

function MaybeMakeWriteableDirectory($path) {
    if(! file_exists($path)) {
        mkdir($path, 0777);
        file_exists($path) && is_dir($path)
            or die("mkdir failed for $path");
    }
}

function ProjectWordcheckPath($projectid) {
    $path = build_path(ProjectPath($projectid), "wordcheck");
    MaybeMakeWriteableDirectory($path);
    return $path;
}

function ProjectTransientPath($projectid) {
    $path = build_path(TRANSIENT_ROOT, $projectid);
    if(! is_dir($path)) {
        mkdir($path, 0777);
    }
    return $path;
}

function ProjectUploadPath($projectid) {
    $path = build_path(ProjectTransientPath($projectid), "loadfiles");
    if(! file_exists($path)) {
        mkdir($path, 0777);
    }
    return $path;
}

function ProjectPath($projectid) {
    global $projects_dir;
    $path = build_path($projects_dir, $projectid);
    MaybeMakeWriteableDirectory($path);
    return $path;
}

function ProjectPagePath($projectid, $pagecode) {
    $path = build_path(ProjectPath($projectid), $pagecode);
    MaybeMakeWriteableDirectory($path);
	return $path;
}

function PageVersionPath($projectid, $pagecode, $version_number) {
    $p = ProjectPagePath($projectid, $pagecode);
    $v = "/v" .$version_number .".txt";
    return build_path($p, $v);
}

function edump($val) {
    echo "\n<pre>\n";
    var_export($val);
    echo "</pre>\n";
}

function rdump($val) {
    echo "\n<pre>\n";
    print_r($val);
    echo "</pre>\n";
}

function dump($val) {
    echo "\n<pre>\n";
    var_dump($val);
    echo "</pre>\n";
}

function pdump($val) {
    return "\n<pre>
        ".print_r($val, true)."
    </pre>\n";
}

function dumpstr($val) {
    return pdump($val);
}

function ldump($val, $len=0) {
    return $len <= 0
        ? pdump($val)
        : "\n<pre
        ".left(print_r($val, true),$len)."
        </pre\n";
}

function trace( $msg ) {
    echo "<br />$msg<br />\n";
}

function error_box($errmsg) {
    return <<<EOT
    <html>
    <head>
    <script language="JavaScript">
    <!--
        alert($errmsg);
        history.back();
    //-->
    </script>
    </head>
    <body></body>
    </html>
EOT;
}

/*
function LanguagesToArray($langstr)
{
    return explode(",", $langstr);
}
*/

function split_language_names($langnames) {
    if(empty($langnames))
    {
        return "English";
    }
    return preg_split("/ +?with +?/", $languages);
}

function split_language_codes($languages) {
    if(empty($languages))
        $languages = "ita";
    foreach(array( "/ +?with +?/", "/ ?, ?/", " +?") as $ptn)
    {
        if( preg_match( $ptn, $languages > 0)) {
            break;
        } 
    }
    return preg_split( $ptn, $languages );
}

function ErrorBox($errmsg) {
    echo "
    <html>
    <head>
    <script language='Javascript [10]'>
    <!--
        alert($errmsg);
        history.back();
    //-->
    </script>
    </head>
    <body></body>
    </html>\n";
}


/*
function today() {
    return new DpDate();
}
*/

function Arg($code, $default = "") {
    if( isset( $_SESSION[$code] ) )
        return $_SESSION[$code] ;
    if( isset( $_POST[$code] ) )
        return $_POST[$code] ;
    if( isset( $_GET[$code] ) )
        return $_GET[$code] ;
    return $default;
}

function IsArg($arg) {
    return isset($_REQUEST[$arg]);
}

// we only take positive integers
function ArgInt($arg, $default = 0) {
    preg_match("/[^0-9]/", $arg)
        ? $default
        : $arg;
}

function ArgBoolean($arg, $default = false) {
    $val = Arg($arg);
    if(empty($val))
        return $default;
    return validate_boolean($val);
}

function validate_boolean($value) {
    if(empty($value))
        return false;
    switch($value) {
        case 1:
        case true:
        case 'yes':
        case 'y':
            return true;
        default:
            return false;
    }
}

function ArgRoundId($default = "") {
    return Arg("roundid", $default);
}

function ArgsLike($pfx) {
    $len = mb_strlen($pfx);
    $ary = array();
    foreach($_REQUEST as $key=>$value)
    {
        if( left($key, $len) == $pfx)
        {
            $ary[$key] = $value;
        }
    }
    return $ary;
}

function ArgArray($name) {
    $a = Arg($name);
    if(!$a)
        return array();
    if(! is_array($a))
        return array($a);
    return $a;
}

function ArgProjectid($default = "") {
    return Arg("projectid", $default);
}

function ArgPageName($default = "") {
    return Arg("pagename", $default);
}

function ArgLangCode($default = "") {
    return Arg("langcode", $default);
}


function QuoteOrNull($code) {
    return empty($code) ? "NULL" : "'$code'" ;
}

/*
    $patterns = array();
    $repls = array();

        // For each CR that isn't immediately followed by a LF,
        // change it to a CRLF. (Convert Max line-ends to DOS.)
        $patterns[] = '/\r(?!\n)/';
        $repls[]    = "\r\n";

        // For each LF that isn't immediately preceded by a CR,
        // change it to a CRLF. (Convert Unix line-ends to DOS.)
        $patterns[] = '/(?<!\r)\n/';
        $repls[]    = "\r\n";

        // Remove any blanks/tabs at the end of each line
        $patterns[] = '/[ \t]+\r\n/';
        $repls[]    = "\r\n";

    $result = preg_replace( $patterns, $repls, $result );

    return addslashes($result);
}
*/

// //////////////////////////////////////////////
// parsing functions
// //////////////////////////////////////////////

// function text_to_words($text) {
    // $ptn = "/".UNICODE_WORD_DELIMITER."+/u";
    // return array_diff(preg_split($ptn, $text), array(""));
// }

function text_to_words($text) {
    $ptn = "~".UWR."~iu";
    $n = preg_match_all($ptn, $text, $m);
    return $m[0];
}

function RegexStringsOffsets(&$text, $langcode = "en") {
    // $ptn = "~[\p{L}\-—–‐―−‒\┈\'\d]+~iu";
    // $ptn = "~[\p{L}\\d]+[\(\)_\+\`\--—–‐―−‒]*~iu";
    // $ptn = "~[\p{L}\p{M}\p{N}\p{Pc}]+['\p{Pd}]*~iu";
    $ptn = "~".UWR."~iu";
    $n = preg_match_all($ptn, $text, $m, PREG_OFFSET_CAPTURE);
    return $m[0];
}
function RegexWordsOffsets(&$text, $langcode = "en") {
    // $edge = "[^\\p{L}\-\^\{\}']+";
    $wdptn = "[\p{L}\-\{\}']+";
    // $ptn = "{$edge}$wdptn{$edge}";
    $ptn = "~$wdptn~u";
    $n = preg_match_all($ptn, $text, $m, PREG_OFFSET_CAPTURE);
    return $m[0];
}

function RegexWordOffsets($word, &$text) {
    $edge1 = "(?<!\p{L})";
    $edge2 = "(?!\p{L})";
    $ptn = "~{$edge1}$word{$edge2}~u";
    $n = preg_match_all($ptn, $text, $m, PREG_OFFSET_CAPTURE);
    return $m[0];
}

?>
